#ifndef LIBVZCONN_CONN_TCPCONNECT_H_
#define LIBVZCONN_CONN_TCPCONNECT_H_

#include "vzconn/base/basicdefines.h"
#include "vzconn/base/bytebuffer.h"
#include "vzconn/conn/vzconnect.h"

namespace vzconn {

class TcpConnect : public VzConnect {
 public:
  virtual ~TcpConnect();
  // Thread safe
  virtual bool Start();

  bool IsConnected() const {
    return state_ == CS_CONNECTED && socket_->is_open();
  }

  boost::asio::ip::tcp::socket& socket() {
    return *socket_;
  }

  virtual const std::string ip_addr() {
    return remote_address_;
  }

 protected:
  virtual void AsyncReadData();
  virtual void ConnectError(const boost::system::error_code& err);
  virtual void TryToWriteData();
  virtual void HandleCloseConnect();
 private:
  bool EnableNagleAlgorithm(bool is_enable);
 private:
  friend class TcpServer;
  friend class VzClient;
  TcpConnect(boost::asio::io_service &io_service);
  boost::shared_ptr<boost::asio::ip::tcp::socket> socket_;
  std::string remote_address_;
};


////////////////////////////////////////////////////////////////////////////////

class BlockVzTcpConnect : public BlockVzConnect {
 public:
  virtual ~BlockVzTcpConnect();
 private:
  BlockVzTcpConnect(boost::asio::io_service &io_service);

  virtual void CloseConnect();

  virtual bool IsConnected() {
    return socket_.is_open();
  }
 private:
  friend class VzClient;
  virtual bool RealySyncWrite(std::vector<boost::asio::const_buffer> &buffers);
  virtual bool RealySyncRead(char *buffer, uint32 buffer_size);
 private:
  boost::asio::ip::tcp::socket socket_;
};

}

#endif // LIBVZCONN_CONN_TCPCONNECT_H_